// 组件通信

import { useState, createContext, useContext } from 'react'

// 父组件
const ComContext = createContext({}) //创建数据源  关键
export function PropsTest() {
  const [comTitle, setComTitle] = useState('公共数据')
  const changeCom = (value: any) => {
    setComTitle(value)
    console.log('公共数据被修改了')
  }

  let state = {
    list: [1, 2, 3],
    name: '父亲的props',
  }
  const clickHandle = (value: string) => {
    console.log('触发了父亲的函数')
    console.log('儿子给我传递的内容：', value)
  }
  // 兄弟通信
  let [brother, setBrother] = useState('')
  const getMsg = (value: string) => {
    console.log(value)
    setBrother(value)
  }
  return (
    <>
      <p>父组件</p>
      {/* 直接变量绑定传递 */}
      <PropsTest2 state={state} brother={brother} clickHandle={clickHandle} />
      <ComContext.Provider value={{ comTitle, change: (value: any) => changeCom(value) }}>
        <PropsTest3 getMsg={getMsg} />
      </ComContext.Provider>
      <hr />
      <button onClick={() => changeCom('我是父亲，我修改了公共数据')}>
        父亲修改公共数据
      </button>
      <hr />
      <ChildrenTest>this is children</ChildrenTest>
      <hr />
      <DefalutProps name={1}></DefalutProps>
    </>
  )
}
// 子组件
function PropsTest2(props: any) {
  // console.log(props)
  let { state, clickHandle, brother } = props
  let title = '我是子组件的内容'
  return (
    <>
      <hr />
      <p>子组件2</p>
      <p>{state.name}</p>
      {state.list.map((item: any) => {
        return <p>{item}</p>
      })}
      <button onClick={() => clickHandle(title)}>
        点我触发父组件函数 ，传递子组件数据给父亲
      </button>
      <p></p>
      <p>兄弟组件传过来的值：{brother}</p>
    </>
  )
}

// 子组件2  兄弟之间传递数据  通过父组件来进行
function PropsTest3(props: any) {
  // console.log(props)
  let b = '这是来自兄弟b组件内容'
  const { getMsg } = props
  return (
    <>
      <hr />
      <p>b子组件3</p>
      <button onClick={() => getMsg(b)}>发送数据 </button>
      <PropsTest4 />
    </>
  )
}

// 跨层传递 爷孙传递
function PropsTest4(props: any) {
  // console.log(props)
  let data: any = useContext(ComContext) || {} // 获取公共数据  关键
  console.log(data)

  return (
    <>
      <p>孙子组件</p>
      <p>{data.comTitle}</p>
      <button onClick={() => data.change('我是儿子，我修改了公共数据')}>
        子组件4修改公共数据
      </button>
    </>
  )
}
// children属性  <ChildrenTest></ChildrenTest>这样写法 标签里面的内容 会被 children属性接受 可以是jsx、函数、文本、标签
function ChildrenTest(props: any) {
  // console.log(props)
  const { children } = props
  return (
    <>
      <p>children属性</p>
      <p>{children}</p>
    </>
  )
}
// 默认props值
interface types {
  name: string | number
}
// function DefalutProps(props: types) {
//   const { name } = props
//   return <p>{name}</p>
// }
// DefalutProps.defaultProps = {
//   name: '默认',
// }

//  最新版不推荐使用.defaultProps设置默认值  而是通过props参数来设置
function DefalutProps({ name = '默认' }: types) {
  return <p>{name}</p>
}

/**
 * 一、props规则校验
 * 1、安装 prop-types 包
 * npm install prop-types
 * 
 * 2、导入 propTypes 对象
 * import propTypes from 'prop-types';
 * 
 * 3、组件名.propTypes = {} 设置组件 传参规则
 * Comp.propTypes = {
	  param: propTypes.array  // Comp组件 的 param 参数必须是 数组类型
  }

 */
